
/************************************************************************
 *
 *
 *       			FileName:epoll_model.cpp
 *
 *         			Author.wzj
 *
 *       			Email:345517039@qq.com
 *
 *      	    		Create:2017-06-22 23:37:35
 *
 *      		    	Description:-
 *
 *
 *************************************************************************/
#include "epoll_model.h"

#include "listenThread.h"
#include "workerThread.h"

/**
 * @brief 
 *
 * @return 
 */
#define DEFAULT_TIMEOUT  -1
#define BUF_SIZE  100 

/**
 * @brief 
 */
epollModel::epollModel(){

}


/**
 * @brief 
 */
epollModel::~epollModel(){

}


/**
 * @brief 
 *
 * @return 
 */
int epollModel::init(){
	int iRet = RET::FAIL;
	iRet  = mem.init(THREAD_LEVEL);
	if ( iRet != RET::SUCCESS){
		fprintf(stderr, "[ ERROR ] EPOLL MODEL MEM INIT ERROR!\n");
		return iRet;
	}
	this->ioname = "epoll";
	this->ctx.maxsize = 100000;
	this->ctx.timeout=DEFAULT_TIMEOUT;
	this->ctx.epollfd=epoll_create(10); //目前先填个10上去;
	try{
		ctx.events= (struct epoll_event *)mem.allocateMemFromMempool(sizeof(struct epoll_event)*this->ctx.maxsize);	
	}catch(std::bad_alloc){
		fprintf(stderr, "[ ERROR ] EPOLL IO MODEL ALLOC MEM OPERATION ERROR!\n");
		return RET::FAIL;
	}
	return RET::SUCCESS; 
}



/**
 * @brief 
 *
 * @param fd
 *
 * @return 
 */
int epollModel::addEvent(int fd){
	int iRet = RET::FAIL;
	if ( fd  <  0){
		fprintf(stderr, "[ ERROR ]EPOLL MODEL IN FUNCTION:%s LINE:%d GET PARA FD: %d IS NOT AVALIABLE!\n",__func__,__LINE__,fd);
		return iRet;
	}
	struct epoll_event ev;
	ev.events = EPOLLIN;
	ev.data.fd = fd; 
	iRet=epoll_ctl(this->ctx.epollfd, EPOLL_CTL_ADD,fd,&ev);
	if(iRet == RET::FAIL){
		fprintf(stderr, "[ ERROR ]EPOLL CTL ADD FD:%d OPERATION FAILURE! IN FUNCTION:%s LINE:%d \n errno:%d", fd, __func__,__LINE__,errno);
		return RET::FAIL;
	}
	return RET::SUCCESS;
}


/**
 * @brief 
 * @param arg
 * @param type
 * @return 
 */
int epollModel::addEvent(void *arg,int type){
	int fd = -1;
	int ret = RET::FAIL;
	if( type == LISTEN_SOCKET){
		struct socket_st *listen = (struct socket_st *)arg;
		fd = listen->fd;
	}else if( type == NETWORK_CONNECTION){
		struct connection *conn = (struct connection *)arg;
		fd = conn->fd;
		Utils::setFdNonblock(fd);
	}
	if(fd != -1){
		struct epoll_event ev;
		ev.events = EPOLLIN;
		ev.data.fd = fd; 
		ret=epoll_ctl(this->ctx.epollfd, EPOLL_CTL_ADD,fd,&ev);
		if(ret == -1){
			return RET::FAIL;
		}
	}
	return RET::SUCCESS;
}


/**
 * @brief 
 *
 * @param arg
 *
 * @return 
 */
int epollModel::delEvent(void *arg){
	int iRet = RET::FAIL;
	struct connection *conn = (struct connection *)arg;
	struct epoll_event ev;
	ev.events=EPOLLIN|EPOLLOUT;
	ev.data.fd = conn->fd;
	iRet = epoll_ctl(this->ctx.epollfd, EPOLL_CTL_DEL, conn->fd,&ev);
	if(iRet == RET::FAIL ){
		fprintf(stderr, "[ ERROR ]EPOLL MODEL DEL FD:%d  OPERATION FAILURE IN FUNCTION:%s LINE:%d\n",conn->fd , __func__,__LINE__);
		return iRet;
	}
	//判断下fd是否存在;
	return  RET::SUCCESS;
}


/**
 * @brief 
 * @param type
 * @param arg
 * @return 
 */
int epollModel::waitForEvent(){
	int nfds = 0;
	int iRet = RET::FAIL;
	nfds = epoll_wait(this->ctx.epollfd, this->ctx.events, this->ctx.maxsize, ctx.timeout);
	if(nfds == RET::FAIL){
		//对错误进行识别和判断;
		if(errno == EINTR){ //被信号所中断;	
			return iRet;
		}
	}
	return nfds;
}



